from decimal import Decimal

from django.contrib.admin.utils import model_format_dict
from django.db.models import ForeignKey
from django.utils import timezone

from user.models import CustomUser
from django.db import models


# Create your models here.
class Combo(models.Model):
    name = models.CharField(max_length=50, verbose_name="套餐名称")
    info = models.TextField(verbose_name="套餐简介", blank=True, null=True)
    price = models.CharField(max_length=10, verbose_name="套餐月租")
    traffic = models.CharField(max_length=50, verbose_name="每月流量(Mb)")
    talk_time = models.CharField(max_length=50, verbose_name="通话时长(分钟)")
    message = models.CharField(max_length=50, verbose_name="短信条数(条)")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="修改时间")

    def __str__(self):
        return f"{self.name} - {self.price}/月"

    class Meta:
        verbose_name = '套餐'
        verbose_name_plural = '套餐'


class Phone(models.Model):
    phonenumber = models.CharField(max_length=11, verbose_name="电话号码")
    user = models.ForeignKey(verbose_name="所属用户", to=CustomUser, on_delete=models.CASCADE)
    is_primary = models.BooleanField(default=False, verbose_name="是否为主号")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更改时间")

    class Meta:
        ordering = ['-is_primary', '-create_time']
        verbose_name = '手机号码'
        verbose_name_plural = '手机号码'

    def __str__(self):
        return self.phonenumber

    def save(self, *args, **kwargs):
        if self.is_primary:
            Phone.objects.filter(user=self.user, is_primary=True).update(is_primary=False)
        super().save(*args, **kwargs)


class PhoneCombo(models.Model):
    phone = models.ForeignKey(to=Phone, on_delete=models.CASCADE, related_name="phone_combo", verbose_name="手机号码")
    combo = models.ForeignKey(to=Combo, on_delete=models.CASCADE, related_name="phone_combos", verbose_name="套餐")
    start_time = models.DateTimeField(auto_now_add=True, verbose_name="开始时间")
    end_time = models.CharField(max_length=19, verbose_name="到期时间",editable=False)
    is_active = models.BooleanField(default=True, verbose_name="是否激活")

    def save(self, *args, **kwargs):
        if self._state.adding and not self.end_time:
            end_time = timezone.now().replace(year=timezone.now().year + 2)
            self.end_time = end_time.strftime("%Y-%m-%d %H:%M:%S")
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.phone.phonenumber} - {self.combo.name}"

    class Meta:
        verbose_name = '号码套餐'
        verbose_name_plural = '号码套餐'


class Balance(models.Model):
    phone = models.OneToOneField(to=Phone, on_delete=models.CASCADE, related_name="balance", verbose_name="手机号码")
    amount = models.DecimalField(max_digits=10, decimal_places=2, default=Decimal("0.00"), verbose_name="余额(元)")
    data_remaining = models.IntegerField(default=0, verbose_name='剩余流量(MB)')
    voice_remaining = models.IntegerField(default=0, verbose_name='剩余语音(分钟)')
    sms_remaining = models.IntegerField(default=0, verbose_name='剩余短信(条)')
    last_updated = models.DateTimeField(auto_now=True, verbose_name='最后更新时间')

    def __str__(self):
        return f"{self.phone.phonenumber} - 余额: ￥{self.amount}"

    def update_allowance(self):
        """根据当前激活套餐刷新剩余流量/语音/短信。"""
        active_combo = (
            PhoneCombo.objects
            .filter(phone=self.phone, is_active=True)
            .order_by('-start_time')
            .first()
        )

        if not active_combo:
            return

        def to_int(value: object) -> int:
            text = str(value).strip()
            # 允许诸如 "1024", "1024 MB", "1024Mb" 等形式
            for sep in [' ', 'MB', 'Mb', 'mb', 'GB', 'Gb', 'gb', '分钟', '条']:
                if sep in text:
                    text = text.split(sep)[0]
                    break
            try:
                return int(text)
            except ValueError:
                return 0

        self.data_remaining = to_int(active_combo.combo.traffic)
        self.voice_remaining = to_int(active_combo.combo.talk_time)
        self.sms_remaining = to_int(active_combo.combo.message)
        self.save(update_fields=['data_remaining', 'voice_remaining', 'sms_remaining', 'last_updated'])

    class Meta:
        verbose_name = '余额信息'
        verbose_name_plural = '余额信息'


class Payment(models.Model):
    phone = models.ForeignKey(to=Phone, on_delete=models.CASCADE, verbose_name="手机号码", related_name="payment")
    amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='缴费金额(元)')
    pay_method = models.CharField(max_length=20, verbose_name="缴费方式", choices=[
        ('alipay', '支付宝'),
        ('wechat', '微信'),
        ('bank', '银行卡'),
        ('cash', '现金')
    ])
    payment_time = models.DateTimeField(auto_now_add=True, verbose_name='缴费时间')
    description = models.CharField(max_length=200, blank=True, verbose_name='备注')

    def __str__(self):
        return f"{self.phone.phonenumber} - ￥{self.amount} - {self.payment_time}"

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        # 缴费后更新余额
        balance, created = Balance.objects.get_or_create(phone=self.phone)
        balance.amount += self.amount
        balance.save()

    class Meta:
        verbose_name = '缴费记录'
        verbose_name_plural = '缴费记录'
        ordering = ['-payment_time']


class UsageRecord(models.Model):
    """使用记录"""
    USAGE_TYPE_CHOICES = [
        ('data', '流量使用'),
        ('voice', '语音使用'),
        ('sms', '短信使用'),
    ]

    phone = models.ForeignKey(to=Phone, on_delete=models.CASCADE, related_name='usage_records', verbose_name='手机号码')
    usage_type = models.CharField(max_length=20, choices=USAGE_TYPE_CHOICES, verbose_name='使用类型')
    amount_used = models.IntegerField(verbose_name='使用量')
    usage_time = models.DateTimeField(auto_now_add=True, verbose_name='使用时间')
    description = models.CharField(max_length=200, blank=True, verbose_name='描述')

    class Meta:
        verbose_name = '使用记录'
        verbose_name_plural = '使用记录'
        ordering = ['-usage_time']

    def __str__(self):
        return f"{self.phone.phonenumber} - {self.get_usage_type_display()} - {self.amount_used}"


